package academic.emailClient.persistence;


import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopScoreDocCollector;
import org.apache.lucene.search.WildcardQuery;
import org.apache.lucene.search.regex.JavaUtilRegexCapabilities;
import org.apache.lucene.search.regex.RegexQuery;
import org.apache.lucene.store.*;
import org.apache.lucene.util.Version;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.logging.Logger;

public class SearchMail {

	static FileReader fr ;
	static BufferedReader buffer;
	private String EMAIL_CLIENT_INDEXING_ROOT = "Email Folders Index";

	private Query query;
	private Query[] quer=new Query[6];
	private BooleanQuery booleanQuery = new BooleanQuery();
	static Logger logger = Logger.getLogger(SearchMail.class.getName());

	/**
	 * This method used to search in the mails that matches the user's criteria and return the Query
	 * @param userQuery
	 * @throws java.text.ParseException 
	 * @throws IOException
	 * @throws ParseException
	 */

	public BooleanQuery createTheQuery(ArrayList<String> userQuery) throws java.text.ParseException{
		booleanQuery = new BooleanQuery();
		
		if(userQuery.get(0)!= null && !userQuery.get(0).equals(""))
		{
			String fromPattern = "*" + userQuery.get(0) + "*";
			Term term = new Term("FROM", fromPattern);							
			quer[0]= new WildcardQuery(term);
			booleanQuery.add(quer[0], BooleanClause.Occur.MUST);
		}
		if(userQuery.get(1)!= null && !userQuery.get(1).equals(""))
		{
			String toPattern = "*" + userQuery.get(1) + "*";
			Term term1 = new Term("TO", toPattern);
			quer[1] = new WildcardQuery(term1);
			booleanQuery.add(quer[1], BooleanClause.Occur.MUST);

		}
		if(userQuery.get(2)!= null && !userQuery.get(2).equals(""))
		{
			String subjectPattern = "*" + userQuery.get(2) + "*";
			Term term2 = new Term("SUBJECT", subjectPattern);
			quer[2] = new WildcardQuery(term2);
			booleanQuery.add(quer[2], BooleanClause.Occur.MUST);

		}	
		if(userQuery.get(3)!= null && !userQuery.get(3).equals(""))
		{
			String s="*"+userQuery.get(3)+"*";
			Term term3 = new Term("BODY_MESSAGE", s );
			RegexQuery query = new RegexQuery (new Term ("BODY_MESSAGE",s)); 
			query.setRegexImplementation(new JavaUtilRegexCapabilities()); 
			logger.info("Searching for: " + query.toString());   	

			quer[3]=query;
			quer[3] = new WildcardQuery(term3);
			booleanQuery.add(quer[3], BooleanClause.Occur.MUST);
			logger.info("Parse"+s);	
			logger.info(booleanQuery.toString());	
		}

		if(userQuery.get(4)!= null &&!userQuery.get(4).equals(""))
		{
			Term term4 = new Term("DATE", changeTheDateFormat(userQuery.get(4))+"*" );
			quer[4] = new WildcardQuery(term4);
			booleanQuery.add(quer[4], BooleanClause.Occur.MUST);
			System.out.println(booleanQuery);
		}

		if (userQuery.size() == 6){

			String pathPattern = userQuery.get(5) + "*";
			Term term5 = new Term("PATH", pathPattern);
			quer[5] = new WildcardQuery(term5);
			booleanQuery.add(quer[5], BooleanClause.Occur.MUST);

		}
		logger.info("Built Query: " + booleanQuery);
		return booleanQuery;
	}


	/**To parse the Date entered by user to filter  
	 * to match the date format in the databse
	 * 	which is YYMMDD
	 * @param old
	 * @return
	 */
	private String changeTheDateFormat(String old){
		SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yy");
		SimpleDateFormat fileDate = new SimpleDateFormat("yyMMdd");
		try {
			Date userDate = sdf.parse(old);	
			String searchDate = fileDate.format(userDate);
			return searchDate;
		}
		catch (Exception e) {
			logger.severe(e.getStackTrace().toString());
			throw new RuntimeException(e);
		}
	}

	/**
	 * this method search the mails that matches the user's search criteria
	 * 
	 * 
	 * @param userQuery
	 * @return
	 * @throws IOException
	 * @throws ParseException
	 * @throws java.text.ParseException
	 */

	public ArrayList<String> searchInMails(ArrayList<String> userQuery) throws IOException, ParseException, java.text.ParseException {
			
		//initialization
		
		ArrayList<String> toDisplay = new ArrayList<String>();
		File indexDir = new File(EMAIL_CLIENT_INDEXING_ROOT);
		Directory fsDir = FSDirectory.open(indexDir);
		IndexSearcher is = new IndexSearcher(fsDir,true);
		TopScoreDocCollector collector =
				TopScoreDocCollector.create(10, true);
		QueryParser queryParser = new QueryParser(Version.LUCENE_CURRENT,
				"FROM",
				new StandardAnalyzer(Version.LUCENE_CURRENT)  );
		query=queryParser.parse("*:*");
		BooleanQuery booleanQuery = new BooleanQuery();
		booleanQuery = createTheQuery(userQuery);
		is.search(booleanQuery, collector);

		ScoreDoc[] hits = collector.topDocs().scoreDocs;
		if(hits.length != 0){
			for ( ScoreDoc scoreDoc : hits ){
				Document d = is.doc(scoreDoc.doc);
				toDisplay.add(d.get("PATH"));
			}
			return toDisplay;
		}else
			return toDisplay;
	}
	public BooleanQuery getQuery(){
		return booleanQuery;
	}

}//class


